package com.ustarlink.listviewanimations;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final CheckBox vpaCB = (CheckBox) findViewById(R.id.vpaCB);
        final CheckBox setTransientStateCB = (CheckBox) findViewById(R.id.setTransientStateCB);
        final ListView listView = (ListView) findViewById(R.id.listView);
        final ArrayList<String> cheesesList = new ArrayList<String>();
        for (int i = 0; i < Cheeses.sCheeseStrings.length; i++){
            cheesesList.add(Cheeses.sCheeseStrings[i]);
        }

        final StableArrayAdapter adapter = new StableArrayAdapter(this,
                android.R.layout.simple_list_item_1, cheesesList);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
                final String item = (String) parent.getItemAtPosition(position);
                if (vpaCB.isChecked()){
                    view.animate().setDuration(1000).alpha(0)
                            .withEndAction(new Runnable() {
                                @Override
                                public void run() {
                                    cheesesList.remove(item);
                                    adapter.notifyDataSetChanged();
                                    view.setAlpha(1);
                                }
                            });
                } else {
                    // Here's where the problem starts - this animation a View object
                    // But that view may get recycled if it is animated out of the container,
                    // and the animation will continue to fade a view that now contains unrelated
                    ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
                    anim.setDuration(1000);
                    if (setTransientStateCB.isChecked()){
                        // Here's the correct way to do this: if you tell a view that it has
                        // transientState, then ListView ill avoid recycling it until the
                        // transientState flag is reset.
                        // a different approach is to use ViewProperAnimator, which sets the
                        // transientState flag internally
                        view.setHasTransientState(true);
                    }
                    anim.addListener(new AnimatorListenerAdapter() {

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            cheesesList.remove(item);
                            adapter.notifyDataSetChanged();
                            view.setAlpha(1);
                            if (setTransientStateCB.isChecked()){
                                view.setHasTransientState(false);
                            }
                        }

                    });
                    anim.start();
                }

            }
        });
    }

    /**
     * Created by cfm on 16-4-4.
     */
    private class StableArrayAdapter extends ArrayAdapter<String> {
        HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
        public StableArrayAdapter(Context context, int resource, List<String> objs) {
            super(context, resource, objs);
            for (int i = 0; i < objs.size(); i++){
                mIdMap.put(objs.get(i), i);
            }
        }

        @Override
        public long getItemId(int position) {
            String item = getItem(position);
            return mIdMap.get(item);
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
}
